package com.xxx.reggie.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xxx.reggie.dto.DishDto;
import com.xxx.reggie.entity.Category;
import com.xxx.reggie.entity.Dish;
import com.xxx.reggie.entity.DishFlavor;
import com.xxx.reggie.entity.Page;
import com.xxx.reggie.exception.BusinessException;
import com.xxx.reggie.mapper.CategoryMapper;
import com.xxx.reggie.mapper.DishFlavorMapper;
import com.xxx.reggie.mapper.DishMapper;
import com.xxx.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
public class DishServiceImpl implements DishService {
    /**
     * 菜品保存方法
     *
     * @param dishDto
     */

    //注入菜品DishMapper
    @Autowired(required = false)
    private DishMapper dishMapper;

    //注入口味DishFlavorMapper
    @Autowired(required = false)
    private DishFlavorMapper dishFlavorMapper;

    @Override
    @Transactional
    public void save(DishDto dishDto) {
        //1.完善菜品对象数据
        //修改时间,添加时间,排序0,是否禁传
        dishDto.setCreateTime(LocalDateTime.now());
        dishDto.setUpdateTime(LocalDateTime.now());
        dishDto.setSort(0);
        dishDto.setStatus(1);//1不禁传

        //2.调用数据访问层添加菜品,要求获取到添加菜后菜品主键id
        dishMapper.save(dishDto);

        //3.遍历口味记录列表完善数据
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            //设置菜品的主键,更新时间,创建时间,更新人,创建人
            flavor.setDishId(dishDto.getId());//设置菜品的主键
            flavor.setUpdateTime(LocalDateTime.now());
            flavor.setCreateTime(LocalDateTime.now());
            flavor.setCreateUser(dishDto.getCreateUser());
            flavor.setUpdateUser(dishDto.getUpdateUser());
        }

        //4.调用数据访问层插入多条口味记录
        dishFlavorMapper.saveBatch(flavors);


        //5.清空缓存所有类别的菜品列表数据
        Set keys = redisTemplate.keys("dish*");
        redisTemplate.delete(keys);

    }


    /**
     * @param page
     * @param pageSize
     * @return page 分页数据
     */
    @Override
    public Page<DishDto> findByPage(Integer page, Integer pageSize) {
        //设置PageHelper的查询第几页和每页多少条
        PageHelper.startPage(page, pageSize);
        //查询所有数据
        List<DishDto> dishDtoList = dishMapper.findByPage();
        //封装所有数据得到PageInfo分页数据
        PageInfo<DishDto> dishDtoPageInfo = new PageInfo<>(dishDtoList);
        //封装成自己的Page对象
        Page<DishDto> disDtoPage = new Page<>();
        disDtoPage.setRecords(dishDtoPageInfo.getList());
        disDtoPage.setTotal(dishDtoPageInfo.getTotal());

        return disDtoPage;
    }

    /**
     * 根据菜品id查询一个菜品和对应多条口味记录数据
     *
     * @param id
     * @return
     */
    @Override
    public DishDto findById(long id) {
        return dishMapper.findById(id);
    }

    /**
     * 修改菜品
     *
     * @param dishDto
     */
    @Override
    @Transactional
    public void updateById(DishDto dishDto) {
        //更新修改时间
        dishDto.setUpdateTime(LocalDateTime.now());

        //调用数据访问层修改菜品数据
        dishMapper.updateById(dishDto);

        //根据菜品id删除对应所有口味记录数据
        dishFlavorMapper.deleteByDishId(dishDto.getId());

        //重新添加口味记录插入数据库(更新人与修改时间)
        List<DishFlavor> flavors = dishDto.getFlavors();

        for (DishFlavor flavor : flavors) {
            //更新人
            flavor.setUpdateUser(dishDto.getUpdateUser());
            //修改时间
            flavor.setUpdateTime(dishDto.getUpdateTime());

            if (flavor.getId() == null) {
                //创建id
                flavor.setDishId(dishDto.getId());
                //创建用户
                flavor.setCreateUser(dishDto.getCreateUser());
                //更新用户
                flavor.setUpdateUser(dishDto.getUpdateUser());
                //更新时间
                flavor.setUpdateTime(LocalDateTime.now());
                //创建时间
                flavor.setCreateTime(LocalDateTime.now());
            }
        }
        //插入到数据库
        dishFlavorMapper.saveBatch(flavors);

        //5.清空缓存所有类别的菜品列表数据
        Set keys = redisTemplate.keys("dish*");
        redisTemplate.delete(keys);
    }

    @Autowired(required = false)
    private CategoryMapper categoryMapper;

    @Autowired(required = false)
    private RedisTemplate redisTemplate;

    /**
     * 根据类别id查询菜品列表的方法
     *
     * @param cid    菜品id
     * @param status 状态
     * @return List
     */
    @Override
    public List<DishDto> findAllByCid(Long cid, Integer status) {

        List<DishDto> dishDtoList = null;

        //从缓存中获取数据
        String key = "dish_" + cid + "_" + status;
        dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);

        if (dishDtoList == null) {

            List<Dish> dishList = dishMapper.findAllByCid(cid, status);

            dishDtoList = new ArrayList<>();

            for (Dish dish : dishList) {
                List<DishFlavor> dishFlavorList = dishFlavorMapper.findAllByDishId(dish.getId());

                DishDto dishDto = new DishDto();
                dishDto.setFlavors(dishFlavorList);

                BeanUtils.copyProperties(dish, dishDto);

                Category category = categoryMapper.findByCid(cid);
                dishDto.setCategoryName(category.getName());

                dishDtoList.add(dishDto);

            }
            //写入缓存中,方便下次直接拿取
            redisTemplate.opsForValue().set(key,dishDtoList);
        }

        return dishDtoList;
    }

    /**
     * 根据id删除菜品
     *
     * @param ids 菜品id
     * @return
     */
    @Override
    @Transactional
    public void deleteById(List<Long> ids) {
        //调用数据访问层查询菜品状态是否为起售或禁售状态.(1起售/0禁售)
        Long count = dishMapper.selectByStatus(ids);
        //判断是否为起售或禁售状态.(1起售/0禁售)
        if (count >= 1) {
            throw new BusinessException("该菜品还在起售状态,无法删除");
        }
        //调用数据访问层批量删除菜品表
        dishMapper.deleteById(ids);

    }


    /**
     * 批量启售菜品,查询是否为起售状态.
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public Integer findByDishId(List<Long> ids, Integer status) {

        /*//查询状态是否为启售状态
        Long count = dishMapper.selectByStatus(ids);

        //判断启售状态是否为1,为1提示已设定为启售状态
        if (count==1){
            throw new BusinessException("该菜品内已是启售状态,无须更改");
        }*/


        //调用数据访问层修改状态
        return dishMapper.findByDishId(ids, status);
    }
}
